//
//  ViewController.m
//  FSH5Pay
//
//  Created by 四维图新科技股份有限公司 on 2022/8/18.
//

#import "ViewController.h"
#import <WebKit/WebKit.h>
#import "UIView+HUD.h"
#import <AFServiceSDK/AFServiceSDK.h>

NSString * const kAliPayCallBackEvent = @"kAliPayCallBackEvent";

NSString * const kWeChatPayCallBackEvent = @"kWeChatPayCallBackEvent";


@interface ViewController ()<WKNavigationDelegate,WKUIDelegate>

@property (nonatomic, weak) WKWebView *webView;

@end

static NSString * const kDaimlerUrl = @"https://test.evzhuangjia.com/morefun/start?token=eyJwaG9uZSI6IjEzNzIwMDI0NTIyIiwidHlwZSI6IkMifQ==";

static NSString * const kAccessToken = @"需要自己补充token";

@implementation ViewController

- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    
}
- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    // Do any additional setup after loading the view.
    
    ///支付宝的通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onAliPayFinish:) name:kAliPayCallBackEvent object:nil];
    ///微信的通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onWeChatPayFinish:) name:kWeChatPayCallBackEvent object:nil];
    
    WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
    config.preferences.javaScriptEnabled = YES;
//    config.preferences.minimumFontSize = 16;
    
    WKUserContentController *userContentController = config.userContentController;
    id<WKScriptMessageHandler> handler = (id<WKScriptMessageHandler>)self;
    ///注册JS方法
    [userContentController addScriptMessageHandler:handler name:@"showAliPay"];
    [userContentController addScriptMessageHandler:handler name:@"showWechatPay"];
    
    WKWebView *webView = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:config];
    self.webView = webView;
    webView.UIDelegate = self;
    webView.navigationDelegate = self;
    
    // 加载方式1
//    NSString *urlString = [NSString stringWithFormat:@"%@?random=%@&Payment-token=%@",self.url, rand,self.token];
    NSURL *url = [NSURL URLWithString:self.url];
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
//    // Charge-Token
    [request addValue:self.token forHTTPHeaderField:@"Payment-Token"]; // Payment-token
    [webView loadRequest:request];
    
    [self.view addSubview:webView];
    
}

- (void)onAliPayFinish:(NSNotification *)notification
{
    NSDictionary *memo = notification.object;
    int resultStatus = [[memo[@"memo"] objectForKey:@"ResultStatus"] intValue];
    NSString *toast = [memo objectForKey:@"memo"][@"memo"];
    if (resultStatus == 6001) {
        [self.webView goBack];
        [self.view showToast:toast duration:2.5];
    }
    // resultStatus == 9000 支付宝支付成功
    UIAlertView *al =[ [UIAlertView alloc]initWithTitle:toast message:@"" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"好的", nil];
    [al show];
}

- (void)onWeChatPayFinish:(NSNotification *)notification{
    ///执行JS方法刷新订单状态
    [self.webView  evaluateJavaScript:@"window.NavinfoH5.updatePaymentStatus" completionHandler:^(id _Nullable reponse, NSError * _Nullable error) {
        
    }];
}

@end

@implementation ViewController (WKNavigationDelegate)

/*
 H5支付总结
 ////////////微信
 一.微信
 0.给app设置的wxURLScheme必须是： *.微信后台注册的一级域名 eg: fusen.evzhuangjia.com
 1.拦截微信支付url
 2.修改Referer为：${wxURLScheme}://
 3.修改redirect_url的Scheme为${wxURLScheme}. 理论上可以修改成除了http/https的任何值
 4.重新发送修改后的请求
 5.完成后需要加载中间页，中间页就是redirect_url的值。
   因为微信支付拿不到支付结果的中间页，所以自己需要开发H5中间页，判断支付状态
 二.微信免密
 
 ////////////支付宝
 一.支付宝
 1.需拦截支付url
 2.修改url中的fromAppUrlScheme参数的值为自己app设置的支付宝URL Scheme。其目的是为了从支付宝返回，可以跳转到原生app
 
 二.支付宝支付并开通免密
 1、拿到支付链接URL，直接跳转到支付宝，这个方法无法返回app，也没有操作成功或失败的回调。
 2、原生集成SDK.
 3、SDK调起支付宝，sign_params参数传支付链接URL，kAFServiceOptionCallbackScheme传app的白名单scheme值，用来返回app。
 
 三.汇总
 1.微信、支付宝的H5支付，本质都是要把当前app的URLScheme传给对应平台的后台。以便结束支付后，从支付app跳转到当前app
 2.微信处理相对繁琐，需要指定redirect_url拿到支付结果状态
 3.当微信指定了redirect_url后，就无法从微信跳回当前app。所以需要先修改redirect_url的scheme以便完成跳转
 4.不用给当前app指定LSApplicationQueriesSchemes白名单。
   默认其它所有的app都可以打开当前app，指定白名单后，只有白名单里的app可以打开
 */
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    NSString  *absoluteString = [navigationAction.request.URL.absoluteString stringByRemovingPercentEncoding];
    NSLog(@"%@",absoluteString);
    NSString *wxH5Scheme = @"lixiaolu.evzhuangjia.com";
    WKNavigationActionPolicy policy = WKNavigationActionPolicyAllow;
    NSURL *URL = navigationAction.request.URL;
    NSString *realUrlString = [navigationAction.request.URL.absoluteString stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    ///1、支付宝支付并开通免密
    if ([navigationAction.request.URL.absoluteString containsString:@"https://render.alipay"]) {
        NSDictionary *params = @{kAFServiceOptionBizParams: @{
                                            @"sign_params": navigationAction.request.URL.absoluteString
                                            },
                                    kAFServiceOptionCallbackScheme: @"alipayDemo",
                                    };
        [AFServiceCenter callService:AFServiceDeduct withParams:params andCompletion:^(AFServiceResponse *response) {
               NSLog(@"签约结果:%@", response.result);
            ///0：成功
            UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"签约结果" message:response.result[@"alipay_user_agreement_page_sign_response"][@"code"] delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
            [alert show];
        }];
    }else if([absoluteString hasPrefix:@"alipays://"] || [absoluteString hasPrefix:@"alipay://"]){///2、支付宝支付
        ///2-1、转原生支付，原生SDK拉起
//        [[AlipaySDK defaultService] payInterceptorWithUrl:[request.URL absoluteString] fromScheme:@"alipayDemo" callback:^(NSDictionary *result) {
//                NSLog(@"%@", result);
//            // isProcessUrlPay 代表 支付宝已经处理该URL
//            if ([result[@"isProcessUrlPay"] boolValue]) {
//                // returnUrl 代表 第三方App需要跳转的成功页URL
//                NSString* urlStr = result[@"returnUrl"];
//                [wself loadWithUrlStr:urlStr];
//            }
//        ];
            ///2-2、 app直接打开，跳转到本地支付宝App
               if ([absoluteString hasPrefix:@"alipays://"] || [absoluteString hasPrefix:@"alipay://"]){
                   NSURL *openedURL = navigationAction.request.URL;
                   NSString *prefixString = @"alipay://alipayclient/?";
                   ///先解码，再替换
                   NSString *urlString = [[self sht_URLDecodedString:absoluteString] stringByReplacingOccurrencesOfString:@"alipays" withString:@"alipayDemo"];
                   ;
                   if ([urlString hasPrefix:prefixString]) {
                       NSRange rang = [urlString rangeOfString:prefixString];
                       NSString *subString = [urlString substringFromIndex:rang.length];
                       ///替换完再编码
                       NSString *encodedString = [prefixString stringByAppendingString:[self sht_URLEncodedString:subString]];
                       openedURL = [NSURL URLWithString:encodedString];
                   }
                   ///打开URL
                   BOOL isSucc = [[UIApplication sharedApplication] openURL:openedURL];
                   if (!isSucc) {
//                       [ToastShow showErrorMessage:@"未安装支付宝，请选择其他验证方式！"];
                   }
                   decisionHandler(WKNavigationActionPolicyCancel);
                   return;
               }

    }else if ([URL.scheme isEqualToString:@"weixin"]){///3、微信支付
        NSDictionary *options = @{
            UIApplicationOpenURLOptionUniversalLinksOnly : @NO
        };
        
        UIApplication *app = [UIApplication sharedApplication];
        [app openURL:URL options:options completionHandler:^(BOOL success) {
            NSLog(@"%@", success ? @"YES":@"NO");
        }];
        
        policy = WKNavigationActionPolicyCancel;
    
    }else if ([realUrlString hasPrefix:@"https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?"]){///3、微信支付
            NSMutableURLRequest *newRequest = [navigationAction.request mutableCopy];
            NSString *curentReferer = [newRequest.allHTTPHeaderFields objectForKey:@"Referer"];
            if ([curentReferer hasPrefix:wxH5Scheme]) {
                policy = WKNavigationActionPolicyAllow;
            } else {
                NSURLComponents *URLComponents = [NSURLComponents componentsWithString:realUrlString];
                NSMutableArray *queryItems = [URLComponents.queryItems mutableCopy] ?: [NSMutableArray array];
                NSString *redirectKey = @"redirect_url";
                NSURLQueryItem *oldRedirectItem = nil;
                for (NSURLQueryItem *item in URLComponents.queryItems){
                    if ([item.name isEqualToString:redirectKey] &&
                        ![item.value hasPrefix:wxH5Scheme])
                    {
                        [queryItems removeObject:item];
                        oldRedirectItem = item;
                        break;
                    }
                }
        
                NSURLQueryItem *newQueryItem = nil;
        
                if (oldRedirectItem) {
                    // 临时url组件
                    NSURLComponents *tmpComponents = [[NSURLComponents alloc] initWithString:[oldRedirectItem.value stringByRemovingPercentEncoding]];
                    tmpComponents.scheme = wxH5Scheme;
                    newQueryItem = [NSURLQueryItem queryItemWithName:redirectKey value:tmpComponents.URL.absoluteString];
                }
        
                [queryItems addObject:newQueryItem];
                URLComponents.queryItems = queryItems;
        
                NSMutableURLRequest *newRequest = [navigationAction.request mutableCopy];
                newRequest.URL = URLComponents.URL;
                NSString *newReferer = [NSString stringWithFormat:@"%@://", wxH5Scheme];
                [newRequest setValue:newReferer forHTTPHeaderField:@"Referer"];
                [webView loadRequest:newRequest];
                // 处理url
                policy = WKNavigationActionPolicyCancel;
            }
        
        }else if ([realUrlString hasPrefix:[NSString stringWithFormat:@"%@://", wxH5Scheme]]){
            /*
             description：如果设置了redirect_url，打开微信的动作完成后，就会加载中间页，
                          但跟实际支付成功或失败逻辑无关，所以这个加载去掉，改为收到微信返回的回调时，手动调JS方法刷新。
             */
            
//           NSString *oldScheme = [NSString stringWithFormat:@"%@://", wxH5Scheme];
//           NSString *newUrl = [realUrlString stringByReplacingOccurrencesOfString:oldScheme withString:@"https://"];
//           NSMutableURLRequest *newRequest = [navigationAction.request mutableCopy];
//
//           newRequest.URL = [NSURL URLWithString:newUrl];
//           [webView loadRequest:newRequest];
//
//           policy = WKNavigationActionPolicyCancel;
       
        }
    
    decisionHandler(WKNavigationActionPolicyAllow);
}
 
- (NSString *)sht_URLDecodedString:(NSString *)urlString
{
    NSString *string = urlString;
    NSString *decodedString=(__bridge_transfer NSString *)CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL, (__bridge CFStringRef)string, CFSTR(""), CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));
    return decodedString;
}
 
- (NSString *)sht_URLEncodedString:(NSString *)urlString
{
    NSString *string = urlString;
    NSString *encodedString = (NSString *) CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
                                                                                                     (CFStringRef)string,
                                                                                                     NULL,
                                                                                                     (CFStringRef)@"!*'();:@&=+$,/?%#[]",
                                                                                                     kCFStringEncodingUTF8));
    return encodedString;
}


@end

@implementation ViewController (WKScriptMessageHandler)
///收到JS的方法，方法需要先注册的
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{

}


@end
